package com.lineage.server.model;

import com.lineage.server.WriteLogTxt;
import com.lineage.server.datatables.ItemTable;
import com.lineage.server.datatables.RecordTable;
import com.lineage.server.datatables.lock.CharItemsReading;
import com.lineage.server.model.Instance.L1ItemInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.serverpackets.S_AddItem;
import com.lineage.server.serverpackets.S_DeleteInventoryItem;
import com.lineage.server.serverpackets.S_ItemStatus;
import com.lineage.server.serverpackets.S_TradeAddItem;
import com.lineage.server.serverpackets.S_TradeStatus;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1TradeItem;
import com.lineage.server.world.World;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1Trade {
  private static final Log _log = LogFactory.getLog(L1Trade.class);
  
  public void tradeAddItem(L1PcInstance pc, int itemObjid, long itemcount) {
    L1PcInstance trading_partner = null;
    try {
      trading_partner = (L1PcInstance)World.get().findObject(pc.getTradeID());
      L1ItemInstance item = pc.getInventory().getItem(itemObjid);
      if (item == null)
        return; 
      if (trading_partner == null)
        return; 
      if (item.isEquipped())
        return; 
      ArrayList<L1TradeItem> map = pc.get_trade_items();
      if (map.size() >= 16)
        return; 
      long count = 0L;
      Iterator<L1TradeItem> iter = map.iterator();
      while (iter.hasNext()) {
        L1TradeItem tg = iter.next();
        if (tg.get_objid() == item.getId())
          count += tg.get_count(); 
      } 
      itemcount = Math.max(0L, itemcount);
      long now_count = itemcount + count;
      boolean checkItem = pc.getInventory().checkItem(item.getItemId(), now_count);
      if (!checkItem) {
        pc.sendPackets((ServerBasePacket)new S_TradeStatus(1));
        trading_partner.sendPackets((ServerBasePacket)new S_TradeStatus(1));
        pc.setTradeOk(false);
        trading_partner.setTradeOk(false);
        pc.setTradeID(0);
        trading_partner.setTradeID(0);
        return;
      } 
      L1TradeItem info = new L1TradeItem();
      info.set_objid(item.getId());
      info.set_item_id(item.getItemId());
      info.set_item(item);
      info.set_count(itemcount);
      pc.add_trade_item(info);
      long out_count = item.getCount() - now_count;
      if (out_count <= 0L) {
        pc.sendPackets((ServerBasePacket)new S_DeleteInventoryItem(item.getId()));
      } else {
        pc.sendPackets((ServerBasePacket)new S_ItemStatus(item, out_count));
      } 
      pc.sendPackets((ServerBasePacket)new S_TradeAddItem(item, itemcount, 0));
      trading_partner.sendPackets((ServerBasePacket)new S_TradeAddItem(item, itemcount, 1));
    } catch (Exception e) {
      if (pc != null)
        pc.get_trade_clear(); 
      if (trading_partner != null)
        trading_partner.get_trade_clear(); 
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void tradeOK(L1PcInstance pc) {
    L1PcInstance trading_partner = null;
    try {
      trading_partner = (L1PcInstance)World.get().findObject(pc.getTradeID());
      if (trading_partner != null) {
        ArrayList<L1TradeItem> map_1 = pc.get_trade_items();
        ArrayList<L1TradeItem> map_2 = trading_partner.get_trade_items();
        HashMap<L1ItemInstance, Long> temp1 = new HashMap<>();
        HashMap<L1ItemInstance, Long> temp2 = new HashMap<>();
        if (!map_1.isEmpty()) {
          Iterator<L1TradeItem> iter = map_1.iterator();
          while (iter.hasNext()) {
            L1TradeItem tg = iter.next();
            if (!CharItemsReading.get().getUserItems(pc.getId(), tg.get_objid(), tg.get_count())) {
              _log.error(
                  "人物交易异常(指定数据数量有误): " + pc.getName() + "/" + pc.getNetConnection().hashCode());
              pc.getNetConnection().kick();
              trading_partner.getNetConnection().kick();
              continue;
            } 
            L1ItemInstance tg_item = pc.getInventory().getItem(tg.get_objid());
            if (tg_item == null) {
              _log.error(
                  "人物交易异常(物品为空): " + pc.getName() + "/" + pc.getNetConnection().hashCode());
              pc.getNetConnection().kick();
              trading_partner.getNetConnection().kick();
              continue;
            } 
            Long count = temp1.get(tg_item);
            if (count == null) {
              temp1.put(tg_item, Long.valueOf(tg.get_count()));
            } else {
              temp1.put(tg_item, Long.valueOf(tg.get_count() + count.longValue()));
            } 
            pc.getInventory().removeItem(tg.get_objid(), tg.get_count());
            if (pc.hasSkillEffect(51234))
              continue; 
            RecordTable.get().recordeTrade(pc.getName(), trading_partner.getName(), 
                tg_item.getAllName(), tg_item.getBless(), (int)tg.get_count(), tg_item.getId(), pc.getIp(), 
                trading_partner.getIp());
          } 
        } 
        if (!map_2.isEmpty()) {
          Iterator<L1TradeItem> iter = map_2.iterator();
          while (iter.hasNext()) {
            L1TradeItem tg = iter.next();
            if (!CharItemsReading.get().getUserItems(trading_partner.getId(), tg.get_objid(), 
                tg.get_count())) {
              _log.error("人物交易异常(指定数据数量有误): " + trading_partner.getName() + "/" + 
                  trading_partner.getNetConnection().hashCode());
              pc.getNetConnection().kick();
              trading_partner.getNetConnection().kick();
              continue;
            } 
            L1ItemInstance tg_item = trading_partner.getInventory().getItem(tg.get_objid());
            if (tg_item == null) {
              _log.error("人物交易异常(物品为空): " + trading_partner.getName() + "/" + 
                  trading_partner.getNetConnection().hashCode());
              pc.getNetConnection().kick();
              trading_partner.getNetConnection().kick();
              continue;
            } 
            Long count = temp2.get(tg_item);
            if (count == null) {
              temp2.put(tg_item, Long.valueOf(tg.get_count()));
            } else {
              temp2.put(tg_item, Long.valueOf(tg.get_count() + count.longValue()));
            } 
            trading_partner.getInventory().removeItem(tg.get_objid(), tg.get_count());
            if (trading_partner.hasSkillEffect(51239))
              continue; 
            RecordTable.get().recordeTrade(trading_partner.getName(), pc.getName(), 
                tg_item.getAllName(), tg_item.getBless(), (int)tg.get_count(), tg_item.getId(), 
                trading_partner.getIp(), pc.getIp());
          } 
        } 
        if (!temp1.isEmpty())
          for (L1ItemInstance item : temp1.keySet()) {
            long count = ((Long)temp1.get(item)).longValue();
            if (item.isStackable()) {
              L1ItemInstance tgItem = ItemTable.get().createItem(item.getItemId());
              tgItem.setCount(count);
              tgItem.setBless(item.getBless());
              trading_partner.getInventory().storeItem(tgItem);
            } else {
              trading_partner.getInventory().storeItem(item);
            } 
            WriteLogTxt.Recording("交易记录", 
                String.valueOf(item.getLogName()) + "(" + item.getItemId() + ")物件objid为" + 
                item.getId() + "交易对象ID" + trading_partner.getId() + "交易对象名字" + 
                trading_partner.getName() + "玩家ID" + pc.getId() + "玩家名字" + 
                pc.getName() + " IP : " + pc.getNetConnection().getIp());
          }  
        if (!temp2.isEmpty())
          for (L1ItemInstance item : temp2.keySet()) {
            long count = ((Long)temp2.get(item)).longValue();
            if (item.isStackable()) {
              L1ItemInstance tgItem = ItemTable.get().createItem(item.getItemId());
              tgItem.setCount(count);
              tgItem.setBless(item.getBless());
              pc.getInventory().storeItem(tgItem);
            } else {
              pc.getInventory().storeItem(item);
            } 
            WriteLogTxt.Recording("交易记录", 
                String.valueOf(item.getLogName()) + "(" + item.getItemId() + ")物件objid为" + 
                item.getId() + "交易对象ID" + trading_partner.getId() + "交易对象名字" + 
                trading_partner.getName() + "玩家ID" + pc.getId() + "玩家名字" + 
                pc.getName() + " IP : " + pc.getNetConnection().getIp());
          }  
        temp1.clear();
        temp2.clear();
        pc.sendPackets((ServerBasePacket)new S_TradeStatus(0));
        trading_partner.sendPackets((ServerBasePacket)new S_TradeStatus(0));
        pc.setTradeOk(false);
        trading_partner.setTradeOk(false);
        pc.setTradeID(0);
        trading_partner.setTradeID(0);
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
      return;
    } finally {
      if (pc != null)
        pc.get_trade_clear(); 
      if (trading_partner != null)
        trading_partner.get_trade_clear(); 
    } 
  }
  
  public void tradeCancel(L1PcInstance pc) {
    L1PcInstance trading_partner = null;
    try {
      trading_partner = (L1PcInstance)World.get().findObject(pc.getTradeID());
      if (trading_partner != null) {
        ArrayList<L1TradeItem> map_1 = pc.get_trade_items();
        ArrayList<L1TradeItem> map_2 = trading_partner.get_trade_items();
        HashMap<Integer, Long> temp1 = new HashMap<>();
        HashMap<Integer, Long> temp2 = new HashMap<>();
        if (!map_1.isEmpty())
          for (Iterator<L1TradeItem> iter = map_1.iterator(); iter.hasNext(); ) {
            L1TradeItem tg = iter.next();
            Long count = temp1.get(Integer.valueOf(tg.get_objid()));
            if (count == null) {
              temp1.put(Integer.valueOf(tg.get_objid()), Long.valueOf(tg.get_count()));
              continue;
            } 
            temp1.put(Integer.valueOf(tg.get_objid()), Long.valueOf(tg.get_count() + count.longValue()));
          }  
        if (!map_2.isEmpty())
          for (Iterator<L1TradeItem> iter = map_2.iterator(); iter.hasNext(); ) {
            L1TradeItem tg = iter.next();
            Long count = temp2.get(Integer.valueOf(tg.get_objid()));
            if (count == null) {
              temp2.put(Integer.valueOf(tg.get_objid()), Long.valueOf(tg.get_count()));
              continue;
            } 
            temp2.put(Integer.valueOf(tg.get_objid()), Long.valueOf(tg.get_count() + count.longValue()));
          }  
        if (!temp1.isEmpty())
          for (Integer key : temp1.keySet()) {
            long count = ((Long)temp1.get(key)).longValue();
            L1ItemInstance tg_item = pc.getInventory().getItem(key.intValue());
            if (tg_item != null) {
              if (count == tg_item.getCount()) {
                pc.sendPackets((ServerBasePacket)new S_AddItem(tg_item));
                continue;
              } 
              pc.sendPackets((ServerBasePacket)new S_ItemStatus(tg_item, tg_item.getCount()));
            } 
          }  
        if (!temp2.isEmpty())
          for (Integer key : temp2.keySet()) {
            long count = ((Long)temp2.get(key)).longValue();
            L1ItemInstance tg_item = trading_partner.getInventory().getItem(key.intValue());
            if (count == tg_item.getCount()) {
              trading_partner.sendPackets((ServerBasePacket)new S_AddItem(tg_item));
              continue;
            } 
            trading_partner.sendPackets((ServerBasePacket)new S_ItemStatus(tg_item, tg_item.getCount()));
          }  
        temp1.clear();
        temp2.clear();
        pc.sendPackets((ServerBasePacket)new S_TradeStatus(1));
        trading_partner.sendPackets((ServerBasePacket)new S_TradeStatus(1));
        pc.setTradeOk(false);
        trading_partner.setTradeOk(false);
        pc.setTradeID(0);
        trading_partner.setTradeID(0);
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } finally {
      if (pc != null)
        pc.get_trade_clear(); 
      if (trading_partner != null)
        trading_partner.get_trade_clear(); 
    } 
  }
  
	/**
	 * 交易取消
	 * 
	 * @param pc
	 */
	public void TradeCancel(final L1PcInstance pc) {
		// int cnt;
		final L1PcInstance trading_partner = (L1PcInstance) World.get()
				.findObject(pc.getTradeID());
		if (trading_partner != null) {
			// 取回自己的交易物品
			final List<L1ItemInstance> player_tradelist = pc
					.getTradeWindowInventory().getItems();

			// 取回对象交易物品
			final List<L1ItemInstance> trading_partner_tradelist = trading_partner
					.getTradeWindowInventory().getItems();

			if (!player_tradelist.isEmpty()) {
				for (L1ItemInstance pcItem : player_tradelist) {
					// 物品转移
					pc.getTradeWindowInventory().tradeItem(pcItem,
							pcItem.getCount(), pc.getInventory());
				}
			}

			if (!trading_partner_tradelist.isEmpty()) {
				for (L1ItemInstance tgPcItem : trading_partner_tradelist) {
					// 物品转移
					trading_partner.getTradeWindowInventory().tradeItem(
							tgPcItem, tgPcItem.getCount(),
							trading_partner.getInventory());
				}
			}

			pc.sendPackets(new S_TradeStatus(1));
			trading_partner.sendPackets(new S_TradeStatus(1));

			pc.setTradeOk(false);
			trading_partner.setTradeOk(false);

			pc.setTradeID(0);
			trading_partner.setTradeID(0);
		}
	}
}
